package edu.mercer.sse.plainpdf;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;

import edu.mercer.sse.error.ReturnCodeException;

/**
 * Application encapsulated by Wrapper Facade.<p>
 * 
 * Configuration specifies applications available and their information.<p>
 * 
 * A Generic - application specific wrapper; i.e., 'Validation'
 * 
 * @see Configuration
 */

public interface UtilityWrapping<A> 

	extends Callable<ExecutionReporting>
{
	/**
	 * Retrieve all Utility Values.<p>
	 * 
	 * All keys as defined for this utility in Configuration.<p>
	 * 
	 * Example:<p>
	 * 
	 *<code>
	 *&#60;entry key="PDFTK_ID"&#62; PDFTK &#60;/entry&#62;<br>
	 *&#60;entry key="PDFTK_LOCATION"&#62; /usr/bin/pdftk &#60;/entry&#62; 
	 *</code><p>
	 * 
	 * Set returned:<p>
	 * 
	 * <code>
	 * "PDFTK_ID", "PDFTK_LOCATION"
	 * </code><p>
	 * 
	 * Empty Set is returned for a Utility lacking any defined keys.<p>
	 * 
	 * @return  Set&#60;String&#62; containing Utility Key of each parameter
	 */
	
	Set<String> getUtilityKeys();
	
	
	/**
	 * Supply a Utility Value.<p>
	 * 
	 * As defined for this utility in Configuration.<p>
	 * 
	 * Example:<p>
	 * 
	 *<code>
	 *&#60;entry key="PDFTK_ID"&#62; PDFTK &#60;/entry&#62;<br>
	 *&#60;entry key="PDFTK_LOCATION"&#62; /usr/bin/pdftk &#60;/entry&#62; 
	 *</code><p>
	 * 
	 * Values are:<p>
	 * 
	 * <code>
	 * "PDFTK", "/usr/bin/pdftk"
	 * </code><p>
	 *
	 * @param key - String utility key; i.e., "PDFTK_LOCATION"
	 * 
	 * @param value - String utility value supplied to utility application for 
	 * 	a valid key; i.e., "PDFTK_LOCATION"
	 * 
	 * @return  this
	 * 
	 * @see UtilityKey
	 * 
	 * @see UtilityValue
	 */
	
	UtilityWrapping<A> setUtilityValue( final String key, 
										final String value );


	/**
	 * Retrieve Utility Value.<p>
	 * 
	 * As defined for this utility in Configuration.<p>
	 * 
	 * Example:<p>
	 * 
	 *<code>
	 *&#60;entry key="PDFTK_ID"&#62; PDFTK &#60;/entry&#62;<br>
	 *&#60;entry key="PDFTK_LOCATION"&#62; /usr/bin/pdftk &#60;/entry&#62; 
	 *</code><p>
	 * 
	 * Keys are:<p>
	 * 
	 * <code>
	 * "PDFTK_ID", "PDFTK_LOCATION"
	 * </code><p> 
	 * 
	 * Values are:<p>
	 * 
	 * <code>
	 * "PDFTK", "/usr/bin/pdftk"
	 * </code><p>
	 * 
	 * @param key - String utility key supplied to utility; i.e., 
	 * 	"PDFINFO_LOCATION"
	 * 
	 * @return  String - value; i.e., "/usr/bin/pdftk"
	 */
	
	String getUtilityValue( final String key );
	
	
	/**
	 * Supply multiple parameter values.<p>
	 * 
	 * Example:<p>
	 * 
	 * <code>
	 * &#60;entry key="PDFTK_ID"&#62; PDFTK &#60;/entry&#62;<br>
	 * &#60;entry key="PDFTK_LOCATION"&#62; /usr/bin/pdftk &#60;/entry&#62; 
	 * </code><p>
	 *
	 * @param values - Map&#60;String,String&#62; containing names and values 
	 * 	utility configuration
	 * 
	 * @return  this
	 * 
	 * @see #setUtilityValue(String, String)
	 */
	
	UtilityWrapping<A> setParameterMap( final Map<String,String> parameterMap );
	
	
	/**
	 * Retrieve Map of multiple parameter names and values.<p>
	 * 
	 * Example:<p>
	 * 
	 * <code>
	 * &#60;entry key="PDFTK_ID"&#62; PDFTK &#60;/entry&#62;<br>
	 * &#60;entry key="PDFTK_LOCATION"&#62; /usr/bin/pdftk &#60;/entry&#62; 
	 * </code><p>
	 * 
	 * @return Map&#60;String,String&#62; containing names and values for 
	 * 	utility configuration
	 * 
	 * @see #getUtilityValue(String) 
	 */
	
	Map<String,String> getParameterMap();


	
	/**
	 * Retrieve all command line variable keys.<p>
	 * 
	 * All keys as defined for this in Configuration.<p>
	 * 
	 * Example:<p>
	 * 
	 * <code>
	 * Examples: FILE_IN, FILE_OUT, PDF_COMPRESSION as in:<p>
	 * 
	 * /usr/bin/tiff2pdf -j -q {PDF_COMPRESSION} -f -o {FILE_OUT} {FILE_IN} 
	 * </code><p>
	 * 
	 * Empty Set is returned for a Utility lacking any defined command line 
	 * 	argument variables.<p>
	 * 
	 * @return  Set&#60;String&#62; containing command line variable keys
	 */
	
	Set<String> getCommandLineVarKeys();
	
	
	/**
	 * Supply a Utility Value.<p>
	 * 
	 * As defined for this utility in Configuration.<p>
	 * 
	 * Examples: FILE_IN, FILE_OUT, PDF_COMPRESSION as in:<p>
	 * 
	 * /usr/bin/tiff2pdf -j -q {PDF_COMPRESSION} -f -o {FILE_OUT} {FILE_IN}<p>
	 * 
	 * Set 'PDF_COMPRESSION' value to '85', result:
	 * 
	 * /usr/bin/tiff2pdf -j -q 85 -f -o {FILE_OUT} {FILE_IN}<p>
	 *
	 * @param key - String utility key; i.e., "PDFTK_LOCATION"
	 * 
	 * @param value - String utility value supplied to utility application for 
	 * 	valid key; i.e., "PDFTK_LOCATION"
	 * 
	 * @return  this
	 * 
	 * @see UtilityKey
	 * 
	 * @see UtilityValue
	 */
	
	UtilityWrapping<A> setCommandLineVarValue( final String key, 
											   final String value );


	/**
	 * Retrieve command line variable value.<p>
	 * 
	 * As defined for this utility in Configuration.<p>
	 * 
	 * Examples: FILE_IN, FILE_OUT, PDF_COMPRESSION as in:<p>
	 * 
	 * /usr/bin/tiff2pdf -j -q {PDF_COMPRESSION} -f -o {FILE_OUT} {FILE_IN}<p>
	 * 
	 * @param String - valid Utility Key of Generic A; i.e., 
	 * 	this
	 * 
	 * @return  String - containing any value previously set;
	 */
	
	String getCommandLineVarValue( final String key );
	
	
	/**
	 * Supply multiple command line variable values.<p>
	 * 
	 * @param values - Map&#60;String,String&#62; containing names and values 
	 * 	for command line argument substitution
	 * 
	 * @return  this
	 */
	
	UtilityWrapping<A> setCommandLineVarMap( final Map<String,String> 
		commandLineVarMap );
	
	
	/**
	 * Retrieve Map of any command line variables names and values.<p>
	 * 
	 * @return Map&#60;String,String&#62; containing names and values for 
	 * 	command line argument substitution
	 */
	
	Map<String,String> getCommandLineVarMap();

	
	/**
	 * Determine if ready to run.<p>
	 * 
	 * @return  Boolean; i.e., true if all parameter values have been provided
	 */
	
	Boolean isReady();
	
	
	/**
	 * Execute application encapsulated by this.<p>
	 * 
	 * Provides ExecutionReporting containing execution results information.<p>
	 * 
	 * If utility application return code is out of configured range, 
	 * a ReturnCodeException checked exception is created.<p>  
	 * 
	 * @return  ExecutionResults - contains output, return code
	 * 
	 * @see ExecutionResults
	 * 
	 * @see #asyncInvoke()
	 * 
	 * @see Future
	 */
	
	ExecutionReporting call() throws ReturnCodeException;	
	
	
	/**
	 * Asynchronous execution.<p>
	 * 
	 * Uses executor service. Can be supplied to constructor. Otherwise, 
	 * 	singlethread executor is used.<p>
	 * 
	 * @return  Future&#60;ExecutionResults&#62;
	 * 
	 * @see #call()
	 * 
	 * @see ExecutionResults
	 * 
	 * @see Future
	 */
	
	Future<ExecutionReporting> asyncInvoke();


}//interface
